package cn.mandifal.cart.service.impl;

import cn.mandifal.cart.service.CartService;
import cn.mandifal.mapper.DpItemMapper;
import cn.mandifal.pojo.Cart;
import cn.mandifal.pojo.DpItem;
import cn.mandifal.pojo.DpOrderItem;
import com.alibaba.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

/**
 * 购物车服务实现类
 * @author shun
 */
@Service
public class CartServiceImpl implements CartService {
    @Autowired
    private DpItemMapper dpItemMapper;

    /**
     * 添加商品到购物车列表
     * @param cartList 商品要填加到的购物车
     * @param itemId 商品sku id
     * @param num 数量
     * @return 添加商品后的购物车
     */
    @Override
    public List<Cart> addGoodsToCartList(List<Cart> cartList, Long itemId, Integer num) {
        //1.得到商品sku信息,并判断此商品是否处于上架状态
        DpItem dpItem = dpItemMapper.selectByPrimaryKey(itemId);
        if (dpItem==null){
            throw new RuntimeException("商品不存在");
        }
        //非上架状态，抛出运行时异常
        if (! "1".equals(dpItem.getStatus())){
            throw new RuntimeException("商品状态不合法");
        }
        //得到商品的商家 id
        String sellerId = dpItem.getSellerId();
        //2.判断购物车列表中是否存在此商家的购物车
        Cart cart = searchCart(cartList, sellerId);
        //3.如果不存在，则创建此商家的购物车，并把商品信息存入
        //说明：cartList 为购物车列表，cart 为商家购物车，orderItemList 为购物明细（或购物明细列表）orderItem 为购物明细项
        if (cart==null){
            //创建此商家的购物车对象
            cart=new Cart();
            //往购物车中添加商家 id
            cart.setSellerId(sellerId);
            //往购物车中添加商家名字
            cart.setSellerName(dpItem.getSeller());
            //往购物车中添加购物车明细
            DpOrderItem orderItem = createOrderItem(dpItem, num);
            List<DpOrderItem> list=new ArrayList<>();
            list.add(orderItem);
            //为购物车添加购物明细
            cart.setOrderItemList(list);
            //将购物车添加到购物车列表中
            cartList.add(cart);
        }else { //4.如果存在则往此商家的购物车中添加此商品
            DpOrderItem orderItem = searchOrderItem(cart.getOrderItemList(), dpItem.getId());
            //如果不存在此商品的购物明细项
            if (orderItem==null){
                //创建此商品的购物明细项
                orderItem=createOrderItem(dpItem,num);
                //添加购物明细项到商家购物车的购物明细中
                cart.getOrderItemList().add(orderItem);
            }else {//存在购物明细项则数量+1
                orderItem.setNum(orderItem.getNum()+num);
                //更改总金额
                orderItem.setTotalFee(new BigDecimal(orderItem.getPrice().doubleValue()*orderItem.getNum()));
                //如果购物车中购物明细项中商品的数量小于等于 0 时，移除购物明细项
                if (orderItem.getNum()<=0){
                    cart.getOrderItemList().remove(orderItem);
                }
                //如果购物车中购物明细的数量等于0，则移除商家购物车
                if (cart.getOrderItemList().size()==0){
                    cartList.remove(cart);
                }
            }
        }
        return cartList;
    }

    /**
     * 判断购物车列表中是否存在此商家的购物车
     * @param cartList 购物车列表
     * @param sellerId 商家 id
     * @return 返回 cart 对象
     */
    private Cart searchCart(List<Cart> cartList,String sellerId){
        for (Cart cart:cartList) {
            if (cart.getSellerId().equals(sellerId)){
                return cart;
            }
        }
        return null;
    }

    /**
     * 创建购物车明细项
     * @param dpItem 要添加的商品 sku
     * @param num 添加的数量
     * @return 返回购物车明细项
     */
    private DpOrderItem createOrderItem(DpItem dpItem,Integer num){
        if (num<0){
            throw new RuntimeException("数量非法");
        }
        DpOrderItem dpOrderItem=new DpOrderItem();
        dpOrderItem.setGoodsId(dpItem.getGoodsId());
        dpOrderItem.setItemId(dpItem.getId());
        dpOrderItem.setTitle(dpItem.getTitle());
        dpOrderItem.setSellerId(dpItem.getSellerId());
        dpOrderItem.setNum(num);
        dpOrderItem.setPicPath(dpItem.getImage());
        dpOrderItem.setPrice(dpItem.getPrice());
        //设置总费用,价格为 Long 类型，num 为 integer 类型，将价格转换成 double 类型相乘，num 会自动往高精度转换。
        // 然后在转换成bigdecimal类型
        dpOrderItem.setTotalFee(new BigDecimal(dpItem.getPrice().doubleValue()*num));
        return dpOrderItem;
    }

    /**
     * 判断购物车明细列表中是否存在此商品
     * @param orderItemList 购物车明细列表
     * @param itemId 商品 sku id
     * @return 返回此商品的购物车明细项
     */
    private DpOrderItem searchOrderItem(List<DpOrderItem> orderItemList,Long itemId){
        for (DpOrderItem dpOrderItem:orderItemList) {
            //判断明细列表中是否存在此商品
            //Long 类型时对象类型，用==判断，每个对象都不相同，所以转换成 long 类型比较
            if (dpOrderItem.getItemId().longValue()==itemId.longValue()){
                return dpOrderItem;
            }
        }
        return null;
    }
    @Autowired
    private RedisTemplate redisTemplate;
    /**
     * 从redis中查询购物车
     * @param username 所登录用户名
     * @return
     */
    @Override
    public List<Cart> findCartListFromRedis(String username) {
        //根据用户名从缓存中查找该用户的购物车列表
        List<Cart> cartList = (List<Cart>) redisTemplate.boundHashOps("cartList").get(username);
        //不让 carlist 为null
        if (cartList==null){
            cartList=new ArrayList();
        }
        return cartList;
    }

    /**
     * 将购物车列表保存到redis
     * @param username  所登录用户名
     * @param cartList redis 中存购物车列表的 key
     */
    @Override
    public void saveCartListToRedis(String username, List<Cart> cartList) {
        redisTemplate.boundHashOps("cartList").put(username,cartList);
    }

    /**
     * 合并购物车
     * @param cartList1 购物车列表
     * @param cartList2 购物车列表
     * @return 返回合并后的购物车
     */
    @Override
    public List<Cart> mergeCartList(List<Cart> cartList1,List<Cart> cartList2){
        for(Cart cart: cartList2){
            for(DpOrderItem orderItem:cart.getOrderItemList()){
                cartList1= addGoodsToCartList(cartList1,orderItem.getItemId(),orderItem.getNum());
            }
        }

        return cartList1;

    }
}
